package com.objectcarpentry.kaylee.ui.menus;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.IParameter;
import org.eclipse.core.commands.Parameterization;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.activities.WorkbenchActivityHelper;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.menus.CommandContributionItem;
import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.ui.views.IViewDescriptor;
import org.eclipse.ui.views.IViewRegistry;

import com.objectcarpentry.kaylee.ui.KayleeUIPlugin;

public class ShowViewMenu extends ContributionItem {

	
	public static final String SHOW_VIEW_ID = "org.eclipse.ui.views.showView"; //$NON-NLS-1$
	public static final String VIEW_ID_PARM = "org.eclipse.ui.views.showView.viewId"; //$NON-NLS-1$
	
	private IWorkbenchWindow window;

	
	private Comparator<CommandContributionItemParameter> actionComparator 
		= new Comparator<CommandContributionItemParameter>() {
		public int compare(CommandContributionItemParameter o1, CommandContributionItemParameter o2) {
			if (collator == null) {
				collator = Collator.getInstance();
			}
			return collator.compare(o1.label, o2.label);
		}
	};

	protected boolean dirty = true;

	private IMenuListener menuListener = new IMenuListener() {
		public void menuAboutToShow(IMenuManager manager) {
			manager.markDirty();
			dirty = true;
		}
	};
	

	private static Collator collator;


	

	/**
	 * Creates a Show View menu.
	 * 
	 * @param window
	 *            the window containing the menu
	 * @param id
	 *            the id
	 */
	public ShowViewMenu(IWorkbenchWindow window, String id) {
		super(id);
		this.window = window;
	}

	public boolean isDirty() {
		return dirty;
	}

	/**
	 * Overridden to always return true and force dynamic menu building.
	 */
	public boolean isDynamic() {
		return true;
	}

	/**
	 * Fills the menu with Show View actions.
	 */
	private void fillMenu(IMenuManager menu) {
		
		// Remove all.
		menu.removeAll();

		// If no page disable all.
		IWorkbenchPage page = window.getActivePage();
		if (page == null) {
			return;
		}

		// If no active perspective disable all
		if (page.getPerspective() == null) {
			return;
		}

		// Get visible actions.
		List<String> viewIds = Arrays.asList(page.getShowViewShortcuts());

		List<CommandContributionItemParameter> actions 
			= new ArrayList<CommandContributionItemParameter>(viewIds.size());
		
		for (String id : viewIds) {
			if (!id.startsWith(KayleeUIPlugin.ID_PREFIX)) {
				continue;
			}
			CommandContributionItemParameter item = getItem(id);
			if (item != null) {
				actions.add(item);
			}
		}
		
		Collections.sort(actions, actionComparator);
		for (CommandContributionItemParameter p : actions ) {
			CommandContributionItem item = new CommandContributionItem(p);
			if (WorkbenchActivityHelper.filterItem(item)) {
				item.dispose();
				continue;
			}
			menu.add(item);
		}
	}

	private CommandContributionItemParameter getItem(String viewId) {
		IViewRegistry reg = PlatformUI.getWorkbench().getViewRegistry();
		IViewDescriptor desc = reg.find(viewId);
		if (desc==null) {
			return null;
		}
		String label = desc.getLabel();
		
		CommandContributionItemParameter parms = new CommandContributionItemParameter(
				window, viewId, SHOW_VIEW_ID,
				CommandContributionItem.STYLE_PUSH);
		parms.label = label;
		parms.icon = desc.getImageDescriptor();
		HashMap<String,String> pm = new HashMap<String,String>(); 
		pm.put(VIEW_ID_PARM, viewId);
		parms.parameters = pm;
		return parms;
	}

	
	public void fill(Menu menu, int index) {
		if (getParent() instanceof MenuManager) {
			((MenuManager) getParent()).addMenuListener(menuListener);
		}

		if (!dirty) {
			return;
		}

		MenuManager manager = new MenuManager();
		fillMenu(manager);
		IContributionItem items[] = manager.getItems();
		if (items.length == 0) {
			MenuItem item = new MenuItem(menu, SWT.NONE, index++);
			item.setText("No Views");
			item.setEnabled(false);
		} else {
			for (int i = 0; i < items.length; i++) {
				items[i].fill(menu, index++);
			}
		}
		dirty = false;
	}
	
}
